package events;

import java.util.List;

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

import eduni.simjava.Sim_entity;
import eduni.simjava.Sim_event;
import eduni.simjava.Sim_port;
import eduni.simjava.Sim_system;
import eduni.simjava.distributions.Sim_geometric_obj;
import eduni.simjava.distributions.Sim_negexp_obj;

public class Source extends Sim_entity {

        private Sim_port out;
        private Sim_port in;

        private RandomData delay;
        private double delayMean;

        // This value is used for DEBUG
        private double mean;

        private long fileSize;
        private List<Client> clients;

        public Source(String name, double fileSizeMean, double mean, List<Client> clients) {
                super(name);
                this.clients = clients;

                this.delay = new RandomDataImpl();
                this.delayMean = mean;

                this.out = new Sim_port("out");
                add_port(this.out);
                
                this.fileSize = (long)fileSizeMean;
                this.mean = mean;
        }

        public void body() {
                
                for(Client client : clients){
                        // Send the processor a job
                        client.setFirstTimeDownloading(Sim_system.clock());
                        
//                        System.out.println("TIME: "+Sim_system.clock()+" CLIENT "+client.get_name()+" REQ "+client.getBlockBeingRequested()+" "+client.getFileBeingDownloaded());
                        
                        sim_schedule(this.out, 0.0, EventType.REQUEST_FILE, client);
                        
                        // Waiting for another client to arrive
                        double sample = this.delay.nextExponential(this.delayMean);
                        sim_pause(sample);
                        // sim_pause(this.mean); Use this call if in DEBUG mode
                        
                }
        }
}
